package com.cskaoyan.javase.oop3._2inner._5anonymous._0introduction;

import sun.security.x509.AVA;

/**
 * 我们已经使用过匿名对象了
 * 匿名对象的含义是这个对象是没有名字，没有引用指向它。
 * 那么匿名内部类，指的就是这个内部类没有名字。
 * 当然成员内部类和静态内部类没法没有名字
 * 所以 匿名内部类指的是"没有名字的局部内部类"。是一种特殊的局部内部类。
 *
 * 匿名内部类仍然定义在局部位置，它是没有名字的局部内部类
 *  如果不直接创建它的对象，这个匿名类是无法使用的。
 *  所以：
 *      匿名内部类不是定义一个类，而是直接创建一个对象
 *      所以它更准确的称呼应该叫“匿名内部类对象”
 *
 *  语法：
 *      new 类名或者接口名(){
 *          // 某类名或接口名的子类的类体
 *      };
 * 解释：
 *      1.new关键字仍然表示创建对象
 *      2.类名可以是普通类类名,也可以是抽象类类名
 *      3.匿名内部类的语法中,隐含了继承/实现
 *          new关键字创建对象
 *          实际上表示创建"类名/接口名"的子类对象
 *      4.语法中的"{}"是:
 *          "类名/接口名"的子类/实现类类体
 *          这个子类/实现类是匿名的
 *      5.紧接第四条,既然"{}"是类体
 *          那么这就意味着"匿名子类"可以新增自身的成员
 *
 *      以上,匿名内部类,最准确,最完整的说法是"匿名的局部内部类子类对象"
 *
 * 以上是定义语法,那么匿名内部类对象,如何使用呢?
 * 有两种方式:
 *      1.用引用接收,用父类引用接收
 *      2.不接收直接使用,相当于使用"匿名对象"
 *
 * 以上两种方式的区别,优缺点:
 *      1.引用接收的优点:
 *          可以多次使用
 *      2.引用接收的缺点:
 *          a.比直接用,要多一步,要稍微麻烦一点
 *          b.不能访问子类独有成员,被父类引用限制了访问范围
 *          而且不能强转,因为子类是匿名的
 *
 *      3.直接使用的优点:
 *          a.更方便一点,更快一点
 *          b.可以访问子类独有成员
 *      4.直接使用的缺点:
 *          一次性
 *
 * @since 15:56
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 创建A的匿名子类对象
        A a = new A() {
            // 匿名子类独有成员
            int num = 10;
            @Override
            public void test() {
                System.out.println("匿名子类的类体");
            }
        };
        a.test();

        // 创建BaseA的匿名子类对象
        new BaseA(){
            @Override
            public void test() {
                System.out.println("抽象类的匿名子类的类体");
            }
        }.test();

        System.out.println(new BaseA() {
            int num = 10;
            @Override
            public void test() {
                System.out.println("抽象类的匿名子类的类体");
            }
        }.num);
    }
}

abstract class BaseA {
    public abstract void test();
}

class A {
    public void test() {
        System.out.println("A");
    }
}